
#ifndef __KEY_DB_H
#define __KEY_DB_H

#include <vector>
#include "SQLiteDB.h"
#include "KeyTableView.h"

#include "../crypt/EncryptionKey.h"
#include "../crypt/DecryptionKey.h"
#include "../crypt/SigningKey.h"
#include "../crypt/CheckingKey.h"

#include "../crypt/EncryptWrapper.h"
#include "../crypt/DecryptWrapper.h"

#define KEY_GENERATE_TYPE_ROOT_ENCRYPT_DECRYPT      AbstractKey::KEY_ASYMMETRIC_PAIR_RSA
#define KEY_GENERATE_TYPE_LEAF_ENCRYPT_DECRYPT      AbstractKey::KEY_ASYMMETRIC_PAIR_RSA
#define KEY_GENERATE_TYPE_ROOT_CHECKING_SIGNING     AbstractKey::KEY_ASYMMETRIC_PAIR_ECDSA
#define KEY_GENERATE_TYPE_LEAF_CHECKING_SIGNING     AbstractKey::KEY_ASYMMETRIC_PAIR_ECDSA
#define KEY_GENERATE_TYPE_ROOT_SSH_CHECKING_SIGNING AbstractKey::KEY_ASYMMETRIC_PAIR_DSA
#define KEY_GENERATE_TYPE_LEAF_SSH_CHECKING_SIGNING AbstractKey::KEY_ASYMMETRIC_PAIR_DSA

/** Class for manipulating a database of keys. */
class KeyDB : public SQLiteDB
{
   public:
      /** Types of marking for key roles and lifetime information. */
      enum keymarkstype {   KEYMARK_EXPENDABLE = 'E',
                            KEYMARK_CHAINLATEST = 'L',
                            KEYMARK_CHAIN = 'C',
                            KEYMARK_CHAINROOT = 'R',
                            KEYMARK_PERMANENT = 'P',
                            KEYMARK_LIFE = 'O' };
      KeyDB(const char *filename, const char *WIPpwd, const char *iownname, const char *ownpwd, int persists);
      ~KeyDB();
      int generateEncDecPairIntoDB(int ischained, int isexpendable,
         const char *name, const char *owner,
         AbstractKey::keypairtype policyoverridekeypair = AbstractKey::KEY_NULL_PAIR);
      int generateSgnChkPairIntoDB(int ischained, int isexpendable, int isforssh,
         const char *name, const char *owner,
         AbstractKey::keypairtype policyoverridekeypair = AbstractKey::KEY_NULL_PAIR);
      static int generateNewEncryptionDecryptionKeys(int generatefunc, const char *name, EncryptionKey **enckey, DecryptionKey **deckey);
      static int generateNewSigningCheckingKeys(int generatefunc, const char *name, SigningKey **sgnkey, CheckingKey **chkkey);
      EncryptWrapper *getEncrypter(const char *enckeyname, const char *sgnkeyname, bool docompress) const;
      DecryptWrapper *getDecrypter(const char *deckeyname, const char *chkkeyname, bool dodecompress) const;
      static int performExternalKeyUpdates(const char *keydb_filename, const char *keydb_WIPpwd,
         const char **file_keys_list, apr_pool_t *mp);
      void deleteAllKeys(const char *keyname) const;
      void updateOwnerKeysToLatest(const char *ownpwd);
      /** Get the encryption table.
       * 
       * @return The encryption table. */
      const KeyTableView *encryptionTable() const { return encryptionkeys; }
      /** Get the decryption table.
       * 
       * @return The decryption table. */
      const KeyTableView *decryptionTable() const { return decryptionkeys; }
      /** Get the signing table.
       * 
       * @return The signing table. */
      const KeyTableView *signingTable() const { return signingkeys; }
      /** Get the checking table.
       * 
       * @return The checking table. */
      const KeyTableView *checkingTable() const { return checkingkeys; }
      /** Get the name of the key database owner (root).
       * 
       * @return Key database owner. */
      const char *getOwnerName() const { return ownname; }
   private:
      /** Own name. */
      char *ownname;
      /** Gets a list of table names, and recreates them before doing
       * so if they don't exist.
       * 
       * @return List of database tables for the key database. */
      std::vector<const char *> *getTableNamesFromCreateTablesIfNecessary();
      /** Pointer to the key table view of the EncryptionKey
       * storage. */
      KeyTableView *encryptionkeys;
      /** Pointer to the key table view of the DecryptionKey
       * storage. */
      KeyTableView *decryptionkeys;
      /** Pointer to the key table view of the SigningKey storage. */
      KeyTableView *signingkeys;
      /** Pointer to the key table view of the CheckingKey storage. */
      KeyTableView *checkingkeys;
      /** Overall work-in-progress password. */
      char *oWIPpwd;
      /** Set of table names for the key. */
      std::vector<const char *> *keytablenames;
};

#endif
